home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 191_01 / clink80.c < prev    next >
C/C++ Source or Header  |  1986-07-08  |  17KB  |  494 lines

  1. /* CLINK/80 v. 6-9-85 compile with -k switch         */
  2. /* Linkage of C/80 source code subroutines           */
  3. /* Phillip L. Emerson   Cleveland State University   */
  4. /* first version, 4-24-84                            */
  5. /* modified 9-17-84 for some filenames in output     */
  6. /* modified 2-20-85 for single pass if keyfile exists*/
  7. /* modified 6-7-85: took out #define DONOTHING, put in
  8.    #define LF,SP; simplified a few routines; hashlist
  9.    structures now used for both data bases -- library
  10.    function intercalls (table1) and program function
  11.    calls netted up (table2). Also, routine netup() was
  12.    modified to erase its tracks to prevent endless
  13.    cycling (stack overflow) with cycling function calls */
  14.  
  15.       /* some modifiable parameters */
  16. #define SAME 0
  17. #define LESS -1
  18. #define MORE 1
  19. #define ONE 1
  20. #define VOID -1
  21. #define NULL 0
  22. #define UNDRSC '\137'   /*assumes ASCII*/
  23. #define BELL '\007'
  24. #define APOSTR '\047'
  25. #define QUOTE '\042'
  26. #define BACKSL '\134'
  27. #define LF '\n'
  28. #define SP '\40'
  29. #define BUFSIZ 5000      /*must hold any lib. func.*/
  30. #define NAMSIZ 20        /*max length of func. names*/
  31. #define HASHSIZ 512      /*size of hash table       */
  32. #define LINSIZ 140       /*source-code max line  ln */
  33. #define FNAMSZ 20        /*max len. of file names   */
  34. #define OFFSET 20        /*buff offset for backup    */
  35. #define MARGA 10         /*error margin for buff ovfl */
  36. #define MARGB 15         /*error margin for buff ovfl */
  37. #define alloc sbrk       /*a C/80 optional primitive alloc */
  38. char progfil[FNAMSZ],libfil[FNAMSZ],keyfil[FNAMSZ],outfil[FNAMSZ];
  39. char *fubuff, *linebuf ;
  40. int prchan,lichan,keychan,ouchan,quotes,apostrs,combal;
  41.  
  42. /* some functs. before main */
  43.  
  44. /* next f name into r, from string starting
  45.    at p -- return 0 if end reached */
  46. char *funam(p,r) char *p,*r; {char *t,*q,*s,*u; int n;
  47.   u = r ;
  48. loop: s = p; r = u ;
  49.    while ((*p) && (*p != '(' )) p++ ;
  50.    if (*p == NULL) return(NULL) ;
  51.    t = p-- ;
  52.    while ((*p == ' ' ) && (p > s)) p-- ;
  53.    q = p ;
  54.    if( !lglname(*q)) { p = ++t ; goto loop ; }
  55.    while ( lglname(*q) && (q >= s)) q-- ;
  56.    q++ ;
  57.    for(n=1; (n < (NAMSIZ-1)) && (q <= p); *r++ = *q++,n++) ;
  58.    *r = NULL;
  59.    if ((q < s) || (n >= (NAMSIZ-1)) || (n <= 0))
  60.       {putstr("error in processing name\n") ;
  61.        putstr(u); putchar(LF); exit(); }
  62.    if (systn(u)) { p = ++t; goto loop; }
  63.    return(++t) ; }
  64.  
  65. /* list of commen system function names to ignore */
  66. #define SNAMES 19  /* nr of names*/
  67. char *sysnam(n) int n;
  68. {static char *name[] = {
  69. "if","for","while","fclose","fopen","getc",
  70. "putc","write","read","getchar","putchar",
  71. "alloc","return","main","seek","ftell",
  72. "ftellr","exec","switch" } ; return(name[n]) ; }
  73.  
  74. /* Mod2 counting of apostrophes and quotes */
  75. char quotap(n) char n; {static char last;
  76.   if(( n == QUOTE) && (last != BACKSL ) && !apostrs)
  77.      quotes = ((quotes+1) % 2) ;
  78.   if(( n == APOSTR) && (last != BACKSL) && !quotes)
  79.      apostrs=((apostrs+1) % 2) ;
  80.   last = n ;
  81.   return(n) ; }
  82.  
  83. /* allocate space for s, store s, and return ptr to it */
  84. char *strsave(s) char *s; {char *p ;
  85.    if (((p=alloc(strlen(s)+1)) == VOID) || (p == NULL))
  86.           return(NULL) ;
  87.    strcpy(p,s); return(p) ; }
  88.  
  89. /* search for string q on p. rtrn ptr to it if so, null if not*/
  90. char *strison(p,q) char *p,*q; {
  91.    for( ; *p ; p++) {if(strisat(p,q)) return(p) ; }
  92.    return(NULL) ; }
  93.  
  94. /* standard getch & ungetch to be used in next routine*/
  95. int getctr ;
  96. char getcbuf[5] ;
  97. char getch()
  98.   { if(getctr) return (getcbuf[--getctr]); return(getc(lichan)) ; }
  99. ungetch(a) char a;
  100.   {getcbuf[getctr++] = a; return; }
  101.  
  102. /* get a char from libchan, ignoring literals & comments */
  103. char gignor()
  104. { char n,m;
  105. loop1: if ((n=getch()) == VOID) return(VOID) ;
  106.    if((n != '/') || quotes || apostrs) return(quotap(n)) ;
  107.    if((m=getch()) != '*') {ungetch(m) ; return(quotap(n)) ; }
  108. loop2: while (((m=getch()) != '*') && (m != VOID))
  109.         {n=getch(); ungetch(n);
  110.          if((m == '/') && (n == '*')) combal++ ; }
  111.    if (m == VOID) return(VOID) ;
  112.    if((m=getch()) != '/') {ungetch(m) ; goto loop2; }
  113.    goto loop1; }
  114.  
  115. oulab() {putl("/* file ",ouchan);putl(outfil,ouchan);putl(" */\n",ouchan);}
  116.  
  117. struct list {
  118. char *hashkey ;
  119. char *defntn ;
  120. struct list *next ; } ;
  121. struct list **table1 ;
  122. struct list **table2 ;
  123.  
  124. /*  BEGINNING OF MAIN PROGRAM */
  125. main(argc,argv) int argc; char *argv[];
  126. {  putstr("CLINK/80 v. 6-9-85\n") ;
  127.   linebuf = alloc(LINSIZ) ;
  128.   table1 = (struct list **) alloc(HASHSIZ*(sizeof(struct list *))) ;
  129.   table2 = (struct list **) alloc(HASHSIZ*(sizeof(struct list *))) ;
  130.   tabinit() ;
  131.   fubuff = alloc(BUFSIZ) ;
  132.   if( (fubuff == NULL) || (fubuff == VOID))
  133.     {putstr("not enough room for buffer\n"); exit(); }
  134.   strcpyn(progfil,argv[1],FNAMSZ-1) ;
  135.   strcpyn(libfil,argv[2],FNAMSZ-1) ;
  136.   strcpyn(keyfil,argv[3],FNAMSZ-1) ;
  137.   strcpyn(outfil,argv[4],FNAMSZ-1) ;
  138.   if (argc >= 2)
  139.       { if ( !strison(progfil,"."))
  140.             strcpy(progfil+strlen(progfil),".B") ;
  141.         if (argc < 5) strcpyc(outfil,progfil,'.') ;
  142.         if (argc < 4) strcpy(keyfil,"LIBKEY.B") ;
  143.         if (argc < 3) strcpy(libfil,"USRLIB.B") ;
  144.         defalt(progfil,keyfil,".B") ;
  145.         defalt(progfil,libfil,".B") ;
  146.         defalt(progfil,outfil,".C") ;
  147.         putchar(LF) ;
  148.         putstr(progfil) ; putstr(" program file\n") ;
  149.         putstr(libfil) ; putstr(" library file\n") ;
  150.         putstr(keyfil) ; putstr(" library key file\n") ;
  151.         putstr(outfil) ; putstr(" output file \n") ;
  152.         putstr("press RETURN (or ENTER) to proceed, Ctrl-C to abort\n") ;
  153.         getchar() ;
  154.         hashup() ;
  155.         prchan = foptst(progfil,"r") ;
  156.         ouchan = foptst(outfil,"w") ;
  157.         oulab() ;
  158.         buildup(1) ;
  159.      }
  160.  else
  161.      {  putstr("\nlibrary file name? ") ;  getstr(libfil) ;
  162.         putstr("\nlibrary keys file name? "); getstr(keyfil) ;
  163.         putstr("wait -- getting library keys\n") ;
  164.         hashup() ;
  165.         putstr("output file name? ") ;  getstr(outfil) ;
  166.         ouchan = foptst(outfil,"w") ; oulab() ;
  167.         for (*progfil='1'; (*progfil) && (*progfil != LF) ; )
  168.           { putstr("input file name? -- ") ;
  169.             putstr("just press RETURN (or ENTER) if no more ") ;
  170.             *progfil = NULL; getstr(progfil) ;
  171.             if ( (*progfil) && (*progfil != LF ) )
  172.               {prchan = foptst(progfil,"r") ;
  173.                putstr("include in output file? (type 0 for no, 1 for yes)\n");
  174.                buildup(getint()) ;
  175.               }
  176.           }
  177.      }
  178.  tidyup() ;
  179.  if (quotes || apostrs || combal)
  180.      {  putchar(LF); putstr("quotes mod2: ") ; printd(quotes) ;
  181.         putchar(LF); putstr("apostrophes mod2: "); printd(apostrs) ;
  182.         putchar(LF) ;
  183.         putstr("occurrences of comment delimiters within comments: ") ;
  184.         printd(combal) ; putchar(LF) ;
  185.      }
  186.  putstr("Linked output file is "); putstr(outfil); putstr("\n\n") ;
  187. }
  188. /*  END OF MAIN PROGRAM */
  189.  
  190. /*  MANY SUBROUTINES FOLLOW -- some of the more general purpose
  191.     ones would ordinarily reside in a library, but this program
  192.     is intended to be fairly self-contained
  193. */
  194.  
  195. /* Manipulation for defaults on file names */
  196. defalt(fpr,fothr,ext) char *fpr,*fothr,*ext;
  197.   {  char *a,temp[FNAMSZ]; int n;
  198.      if( !strison(fothr,":") && (a = strison(fpr,":") ) )
  199.          {  if ( n = a - fpr)
  200.              {  strcpyn(temp,fpr,n+1) ;
  201.                 strcpy(temp+n+1,fothr) ;
  202.                 strcpy(fothr,temp) ;
  203.              }
  204.          }
  205.      if( !strison(fothr,".") ) strcpy(fothr+strlen(fothr),ext) ;
  206.   }
  207.  
  208. /* copy t to s up to but not including 1st instance of char c */
  209. strcpyc(s,t,c) char *s,*t,c;
  210.   { while( (*s++ = *t++) != c)  ; *(--s) = NULL ; }
  211.  
  212. /* tabinit,hash,look,insert are FUNCTIONS FOR HASHING FUNCTION CALLS UNDER
  213.      FUNCTION NAMES
  214. */
  215.  
  216. tabinit()
  217.   {int n; for (n=0; n < HASHSIZ ; n++) table1[n] = table2[n]=NULL ;}
  218.  
  219. hash(s) char *s; {int val;
  220.   for (val=0; *s ;) val += *s++; return(val % HASHSIZ) ; }
  221. struct list *look(s,table) char *s; struct list **table;
  222.   {struct list *p ;
  223.    for (p=table[hash(